package script

import (
	"game/core"
	"game/core/tools"
	_ "image/png"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/inpututil"
	"github.com/solarlune/resolv"
)

type Player struct {
	core.Sprite
	count int
}

func NewPlayer() *Player {
	player := &Player{
		Sprite: core.Sprite{
			Position: &resolv.Vector{X: 0, Y: 0},
			Scale:    &resolv.Vector{X: 0.5, Y: 0.5},
			Image:    PlayerImg,
		},
	}
	player.SetPosition(resolv.NewVector(512/2, 768-player.GetWH().Y))
	wh := player.GetWH()
	player.Collision = resolv.NewRectangle(player.GetCenter().X, player.GetCenter().Y, wh.X-30, wh.Y-30)

	player.NewTimer().StartTimer(0.5, func() {
		p := player.GetCenter()
		AddNode(GG, core.LayerBullet, NewBullet(&p))
	}, true)

	player.NewTimer().StartTimer(1, func() {
		if player.count%2 == 0 {
			player.SpawnEnemy1(resolv.NewVector(float64(tools.MRand(40, 470)), 0))
		}

		if player.count%10 == 0 {
			for i := 1; i < 4; i++ {
				player.SpawnEnemy2(resolv.NewVector(0+float64(i*50), 200-float64(i*50)), core.ProjectileMovementOption{
					Lifetime: 10,
					// Direction: resolv.NewVector(0, 100),
					// Gravity:   resolv.NewVector(100, 0),
					// Speed:     1,
					// Direction: resolv.NewVector(1, 0),
					// Speed:     300,
					// Gravity:   resolv.NewVector(0, 98),

					// Direction: resolv.NewVector(0.707, -0.707), // 45度向上
					// Speed:     400,
					// Gravity:   resolv.NewVector(0, 500),

					Direction:    resolv.NewVector(1, 0),
					Speed:        200,
					Acceleration: resolv.NewVector(-50, 0), // 水平风力
					Gravity:      resolv.NewVector(0, 98),
				})
			}
		}

		// if player.count%10 == 0 {
		// 	for i := 1; i < 4; i++ {
		// 		player.SpawnEnemy2(resolv.NewVector(500+float64(i*50), 0-float64(i*50)), core.ProjectileMovementOption{
		// 			Lifetime: 10,
		// 			// Direction: resolv.NewVector(0, 100),
		// 			// Gravity:   resolv.NewVector(100, 0),
		// 			// Speed:     1,
		// 			// Direction: resolv.NewVector(1, 0),
		// 			// Speed:     300,
		// 			// Gravity:   resolv.NewVector(0, 98),

		// 			// Direction: resolv.NewVector(0.707, -0.707), // 45度向上
		// 			// Speed:     400,
		// 			// Gravity:   resolv.NewVector(0, 500),

		// 			Direction:    resolv.NewVector(-1, 0),
		// 			Speed:        160,
		// 			Acceleration: resolv.NewVector(0, 0), // 水平风力
		// 			Gravity:      resolv.NewVector(0, 98),
		// 		})
		// 	}
		// }

		player.count++
		if player.count > 100 {
			player.count = 0
		}
	}, true)

	return player
}

func (p *Player) Update(dt float64) error {
	//p.UpdateTimer(dt)

	movement := resolv.NewVectorZero()
	//maxSpd := 4.0
	//friction := 0.5
	//accel := 0.5 + friction

	if d := inpututil.KeyPressDuration(ebiten.KeyUp); d > 0 {
		movement.Y -= 5
	}
	if d := inpututil.KeyPressDuration(ebiten.KeyDown); d > 0 {
		movement.Y += 5
	}
	if d := inpututil.KeyPressDuration(ebiten.KeyLeft); d > 0 {
		movement.X -= 5
	}
	if d := inpututil.KeyPressDuration(ebiten.KeyRight); d > 0 {
		movement.X += 5
	}

	p.MoveVec(movement)

	p.Collision.IntersectionTest(resolv.IntersectionTestSettings{
		TestAgainst: p.Collision.SelectTouchingCells(1).FilterShapes(),
		OnIntersect: func(set resolv.IntersectionSet) bool {
			if set.OtherShape.Tags().Has(core.TagWall) {
				p.MoveVec(set.MTV)
			}
			return true
		},
	})
	//fmt.Println(p.Collision.Center().X, p.Collision.Center().Y)
	return nil
}

func (p *Player) Draw(screen *ebiten.Image) {
	op := &ebiten.DrawImageOptions{}

	op.GeoM.Scale(p.Sprite.Scale.X, p.Sprite.Scale.Y)
	op.GeoM.Translate(p.Position.X, p.Position.Y)

	screen.DrawImage(p.Image, op)
}

func (p *Player) SpawnEnemy1(positon resolv.Vector) {
	enemy := NewEnemy(positon, core.ProjectileMovementOption{
		Lifetime:  10,
		Direction: resolv.NewVector(0, 1),
		Gravity:   resolv.NewVector(0, 0),
		Speed:     100,
	})
	AddNode(GG, core.LayerEnemy, enemy)
}

func (p *Player) SpawnEnemy2(positon resolv.Vector, options core.ProjectileMovementOption) {
	enemy := NewEnemy(positon, options)
	//rand := tools.MRand(0, 2)
	// if rand == 0 {
	// 	enemy.ProjectileMovement.Gravity.X = -enemy.ProjectileMovement.Gravity.X
	// }

	AddNode(GG, core.LayerEnemy, enemy)
}
